#ifndef _cesium_timed_monitor_stage_hpp_
#define _cesium_timed_monitor_stage_hpp_

#include "cesium/stages/monitor.hpp"

namespace Cesium {

template<typename VarType, typename TimerType>
class TimedMonitorStage : public MonitorStage<VarType> {
public:
    typedef typename TimerType::DurationType DurationType;
    typedef typename TimerType::TimeType TimeType;

    TimedMonitorStage(VarType* var, TimerType _timer, DurationType _period)
     : MonitorStage<VarType>(var), timer(_timer), period(_period)
    {
        lastDeadline = timer.current();
        registerTimerCallback();
    }

    TimedMonitorStage(VarType* var, TimerType _timer, DurationType _period, Stage* sink)
     : MonitorStage<VarType>(var, sink), timer(_timer), period(_period)
    {
        lastDeadline = timer.current();
        registerTimerCallback();
    }

private:
    void handleTimer() {
        MonitorStage<VarType>::fire();
        registerTimerCallback();
    }

    void registerTimerCallback() {
        lastDeadline = lastDeadline + period;
        timer.timer(lastDeadline, boost::bind(&TimedMonitorStage<VarType, TimerType>::handleTimer, this));
    }

    TimerType timer;
    DurationType period;
    TimeType lastDeadline;
}; // class TimedMonitorStage

} // namespace Cesium

#endif //_cesium_timed_monitor_stage_hpp_
